package cn.juque.workflow.service.task;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.juque.workflow.annotation.ProcessInfo;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.task.Task;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>BusinessTaskRender</li>
 * </ul>
 * @date 2023-02-03 08:04:26
 **/
@Slf4j
@Service("businessTaskRender")
public class BusinessTaskRender {

    private static final Map<String, String> MAP = MapUtil.newHashMap();

    @Resource
    private TaskService taskService;

    public IBusinessTaskService renderByTaskId(String taskId) {
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        return render(MAP.get(task.getProcessDefinitionId()));
    }

    public IBusinessTaskService render(String processDefinitionKey) {
        return SpringUtil.getBean(MAP.get(processDefinitionKey));
    }

    /**
     * 初始化
     */
    public void init() {
        Map<String, IBusinessTaskService> map = SpringUtil.getBeansOfType(IBusinessTaskService.class);
        MAP.clear();
        map.forEach((k, v) -> {
            // 从代理对象获取被代理的对象
            Object target = AopProxyUtils.getSingletonTarget(v);
            if (null == target) {
                log.error("found aop object is null, class:{}", v.getClass());
                return;
            }
            if (AnnotationUtil.hasAnnotation(target.getClass(), ProcessInfo.class)) {
                String id = AnnotationUtil.getAnnotationValue(target.getClass(), ProcessInfo.class, "processDefinitionKey");
                MAP.put(id, k);
            }
        });
    }
}
